#ifndef __zdc_h__
#define __zdc_h__
#include "zluaobj.h"

// err: errno, <0 for exception, ret1 is errmsg
//						 >=0 is call success, ret1 is the first return value, ret2n is the 2...n return values
// return int: you need return <=0,if you return >0, callback function will be keep for next match call.
typedef int (*ZACALL_CB)(void* userp1,void* userp2,int err,zVar& ret1,zVar& ret2n);
class ZUTIL_API ZACALLOBJ
{
public:
	virtual int cb(int err,zVar& ret1,zVar& ret2n)=0;
};
class ZDal;
class ZNode;
class ZUTIL_API ZNode
{
public:
	ZNode(ZDal&);
	ZNode(ZDal&, const char*);
	ZDal& m_dal;
	zLuaObj m_node;
	zLuaObj m_user;

	zLuaObj m_lasterr;
	void ClearLastErr(){m_lasterr.SetNil();};
	const char* LastErr(){return m_lasterr.getString();}
	int AttachNode(const char* nid);
	bool IsAttached() const;
public:
	int Call(const char* fun,zVar* args,zVar* r1,zVar* r2n);	
	int aCallCB(ZACALL_CB cb,void* userp1,void* userp2,const char* fun,zVar* args);
	int aCallCB(ZACALLOBJ* cb,const char* fun,zVar* args);
	int aCall(const char* fun,zVar* args);
	int Set(zVar* a,zVar* pv);
	int UnSet(zVar* a);
	int UpdateSub(const char* subnode,zVar* pv);
	int CreateSub(const char* sub,zVar* mc);
	int DeleteSub(const zVar* sub);
	int FetchSub(const zVar* tmpl,int lvl, zVar* r1);
};

class ZUTIL_API ZDal
{
public:
	ZLuaEnv& m_env;
	zLuaObj m_api_callact;
	zLuaObj m_api_asynccall;
	zLuaObj m_api_set;
	zLuaObj m_api_unset;
	zLuaObj m_api_updatesub;
	zLuaObj m_api_createsub;
	zLuaObj m_api_deletesub;
	zLuaObj m_api_fetch_node;
public:
	zLuaObj m_app;
public:
	ZDal(ZLuaEnv& env);
	int Init();
	int AttachDal(const char* GlobalName);
public:
	
};
#endif
